package com.tmpt.freemarker.exec;

import com.tmpt.dto.*;
import com.tmpt.service.ITemplateService;
import com.tmpt.utils.JsonMap;
import com.tmpt.utils.StringUtils;
import com.tmptSource.dto.A3jeeCodingDto;
import com.tmptSource.service.intf.IA3jeeCodingService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by wxy on 2017/1/28.
 */
public class FreemarkerGen {

    private A1TemplateTableDto templateTable;
    private ITemplateService templateService;
    private IA3jeeCodingService a3jeeCodingService;
    private String prjPath = "/zpmng/";
    public String _keyRandom = "";
    private FmPageUtils fmPageUtils ;
    private FmUtils fmUtils ;
    private String datasource = "dsA";
    private List<A3jeeCodingDto> a3jeeCodingDtoList;

    /**
     *
     * @param _keyRandomList
     * @param type type=1：生成web层；type=2：生成service层; type=3:生成所有
     */
    public void execute(List<String> _keyRandomList, int type){

        ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
        templateService = (ITemplateService) ctx.getBean("templateService");
        a3jeeCodingService = (IA3jeeCodingService) ctx.getBean("a3jeeCodingService");
        a3jeeCodingDtoList = a3jeeCodingService.selectAll().getResultList();

        for(String _keyRandom : _keyRandomList) {
            this._keyRandom = _keyRandom;
            this.initTemplateTable();
            try {
                this.genFreemaker(type);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) throws Exception {
        List<String> _keyRandomList = new ArrayList<String>();
        /*_keyRandomList.add("20161026170402423");//模板管理
        _keyRandomList.add("201710082026");//员工管理*/
        //_keyRandomList.add("ow_task");
        /*_keyRandomList.add("20161023201654628");//公司管理
        _keyRandomList.add("a2dept");//部门管理
        _keyRandomList.add("20161027085902421");//模板表列管理 a1templatecolumn
        _keyRandomList.add("20161027141302422");//右击菜单 a1templaterightmenu
        _keyRandomList.add("20161026155754821");//日志
        _keyRandomList.add("20150423145252903");//汇总
        _keyRandomList.add("t_freight_rule_info");//运费管理*/

        FreemarkerGen freemarkerGen = new FreemarkerGen();
        freemarkerGen.execute(_keyRandomList,1);
    }


    private FmPageUtils initTemplateTable(){
        templateTable = templateService.getTemplateTable(_keyRandom);
        this.datasource = templateTable.getDataSource();

        System.out.println("----this.datasource-"+this.datasource);
        if(StringUtils.isNull(datasource)){this.datasource = "dsA";}
        this.fmPageUtils = new FmPageUtils(templateService,templateTable,_keyRandom);
        System.out.println("----this.datasource-"+this.datasource);
        this.fmUtils = new FmUtils(this.datasource);
        return fmPageUtils;
    }

    /**
     *
     * @param type type=1：生成web层；type=2：生成service层; type=3:生成所有
     * @throws Exception
     */
    public void genFreemaker(int type) throws Exception {
        //取数据库列类型和table的alias（Map<String,String>）
        Map<String,String[]> paramMap = new HashMap<String, String[]>();
        paramMap.put("_keyRandom",new String[]{_keyRandom});
        paramMap.put("pageCurrent",new String[]{"1"});
        paramMap.put("pageSize",new String[]{"10"});
        paramMap.put("sortOrder",new String[]{"desc"});
        paramMap.put("sortColumn",new String[]{"id"});
        //map to jsonstring
        String paramJson = JsonMap.map2Json(paramMap);
        System.out.println("json:" + paramJson);
        Result resultObj =  templateService.genSql4DynamicDS(paramJson);
        Map<String,Map<String,String>> dbcolumnsProperty = (Map<String,Map<String,String>>)resultObj.getResultMap().get("dbcolumnsProperty");
        Map<String,String> columnAliasMap = (Map<String,String>)resultObj.getResultMap().get("columnAliasMap");
        Map<String,String> columnTableMap = (Map<String,String>)resultObj.getResultMap().get("columnTableMap");

        //主键和数据类型
        String primaryKey = templateTable.getPrimaryKey();
        String primaryKeyDbType = dbcolumnsProperty.get(templateTable.getTableName()+"_"+primaryKey.toLowerCase()).get("data_type");
        String primaryKeyDbTypeLower = primaryKeyDbType.toLowerCase();
        String primaryKeyDataType4JavaEncap = "";
        if(primaryKeyDbTypeLower.equals("int")){
            primaryKeyDataType4JavaEncap = "Integer";
        }else if(primaryKeyDbTypeLower.equals("long") || primaryKeyDbTypeLower.equals("bigint")){
            primaryKeyDataType4JavaEncap = "Long";
        }

        //选择optionId时，filedList是要隐藏的域
        String hiddenFiledsJson = fmUtils.dealHiddenFiledsJson(templateTable);

        //生成类名称
        String tableName = templateTable.getTableName();
        String className = FmUtils.switch2Property(templateTable.getTableName());
        //第一个字母大写
        String tableNameFirstWordUpper = FmUtils.firstWord2Upper(tableName);
        String tableNameFirstWordLower = FmUtils.firstWord2Lower(tableName);
        String classNameFirstWordUpper = FmUtils.firstWord2Upper(className);
        String classNameFirstWordLower = FmUtils.firstWord2Lower(className);

        //把数据库列的一些属性封装进来
        List<Map<String,Object>> columnList = new ArrayList<Map<String, Object>>();
        //can add/edit column
        List<Map<String,Object>> columnCanAddList = new ArrayList<Map<String, Object>>();
        //need sum column list
        List<Map<String,Object>> columnNeedSumList  = new ArrayList<Map<String, Object>>();
        //query: mapper.xml中查询条件列 where子句
        List<Map<String,Object>> conditionColumnMapList = new ArrayList<Map<String, Object>>();
        //列多选项情况
        List<A1TemplateColumnDto> templateTableColumnOptionList = templateService.getTemplateTableColumnOptionList(_keyRandom);
        //整理‘列’和‘可编辑列’
        fmUtils.dealColumnList(templateTable, dbcolumnsProperty, columnList, columnCanAddList, columnNeedSumList,
                conditionColumnMapList, columnAliasMap,columnTableMap,templateTableColumnOptionList);
        boolean needSum = columnNeedSumList.size()>0?true:false;

        //整理可编辑列成字符串，mapper.xml中insert和update相关列使用字符串
        //can add/edit column
        StringBuffer sbCanAddColumn = new StringBuffer();
        StringBuffer sbCanAddColumnValue = new StringBuffer();
        StringBuffer sbCanEditColumn = new StringBuffer();
        fmUtils.dealCanEditColumn(columnCanAddList,sbCanAddColumn,sbCanAddColumnValue,sbCanEditColumn);
        String canAddColumnStr = sbCanAddColumn.toString();
        String canAddColumnValueStr = sbCanAddColumnValue.toString();
        String CanEditColumnStr = sbCanEditColumn.toString();

        //查询字段列 eg:select c1,c2,c3  mapper.xml中使用
        StringBuffer sb4columnStr = new StringBuffer();
        fmUtils.dealColumnstr4Select(templateTable,columnList,sb4columnStr);
        String columnStr = sb4columnStr.toString();

        //字段的sum string eg: select sum(balance) from table1 mapper.xml中使用
        StringBuffer sb4columnSumStr = new StringBuffer();
        /*List<Map<String,String>> sumTitleList = new ArrayList<Map<String, String>>();*/
        Map<String,String> sumTitleMap = new HashMap<String, String>();
        fmUtils.dealNeedSumColumn(columnNeedSumList, sb4columnSumStr,sumTitleMap);
        String columnSumStr = sb4columnSumStr.toString();

        //pages
        Map<String, Object> columnsTag = fmPageUtils.getColumnList(dbcolumnsProperty,columnTableMap);
        String templateTableColumnOptionJson = fmPageUtils.getTemplateTableColumnOptionJson();

        //struts.xml/dubbo.xml muilt
        List<Map<String,String>> strXmlList = new ArrayList<Map<String, String>>();
        Map<String,String> strXmlMap;
        if(a3jeeCodingDtoList!=null){
            for(A3jeeCodingDto jeeCodingDto:a3jeeCodingDtoList){
                strXmlMap = new HashMap<String, String>();
                strXmlMap.put("classNameFirstWordLower",jeeCodingDto.getModelName());
                strXmlMap.put("classNameFirstWordUpper",FmUtils.firstWord2Upper(jeeCodingDto.getModelName()) );
                strXmlList.add(strXmlMap);
            }
        }

        //gen enums
        List<Map> optionDataList = fmUtils.queryOptionDataListBySearch(templateService);
        List<Map> option4ColumnSelfList = fmUtils.queryOption4ColumnSelfList(templateTable);

        //freemarker 参数
        Map map = new HashMap();
        map.put("datasource", this.datasource);
        map.put("tableNameFirstWordUpper", tableNameFirstWordUpper);
        map.put("tableNameFirstWordLower", tableNameFirstWordLower);
        map.put("classNameFirstWordUpper", classNameFirstWordUpper);
        map.put("classNameFirstWordLower", classNameFirstWordLower);
        map.put("columnList", columnList);
        map.put("columnStr", columnStr);//mapper.xml Base_Column_List
        map.put("tableNameSql",StringUtils.isNull(templateTable.getTableNameSql())?templateTable.getTableName():templateTable.getTableNameSql());
        map.put("tableName",templateTable.getTableName());
        map.put("className",className);
        map.put("primaryKey", primaryKey);
        map.put("foreignKey", templateTable.getForeignKey());
        map.put("foreignKey_PropertyFormat", FmUtils.switch2Property(templateTable.getForeignKey()));
        map.put("primaryKey_PropertyFormat", FmUtils.switch2Property(primaryKey));
        map.put("primaryKeyDbType", primaryKeyDbType);
        map.put("primaryKeyDbTypeLower", primaryKeyDbTypeLower);
        map.put("primaryKeyDataType4JavaEncap", primaryKeyDataType4JavaEncap);
        map.put("primaryKeyFirstWordUpper", FmUtils.firstWord2Upper(templateTable.getPrimaryKey()));
        map.put("conditionColumnMapList", conditionColumnMapList);
        map.put("tableAliasName", templateTable.getTableAliasName());
        //can add/edit column
        map.put("columnCanAddList", columnCanAddList);
        map.put("canAddColumnStr", canAddColumnStr);
        map.put("canAddColumnValueStr", canAddColumnValueStr);
        map.put("CanEditColumnStr", CanEditColumnStr);
        //enum
        map.put("optionDataList", optionDataList);
        map.put("option4ColumnSelfList", option4ColumnSelfList);
        //need sum column str
        map.put("needSum", needSum);
        map.put("columnSumStr", columnSumStr);
        map.put("sumTitleMap", sumTitleMap);
        //struts.xml/dubbo.xml muilt
        map.put("strXmlList", strXmlList);

        //pages
        map.put("path", prjPath);
        map.put("_keyRandom", _keyRandom);
        map.put("columnsTag", columnsTag);
        map.put("templateTable", templateTable);
        map.put("templateTableColumnOptionJson", templateTableColumnOptionJson);
        map.put("rightMenuContext", fmPageUtils.getRightMenuList());
        map.put("templateTableColumnOptionList", fmPageUtils.getTemplateTableColumnOptionList());
        //map.put("conditionColumnDtoList", conditionColumnDtoList);
        map.put("sortColumnList", fmPageUtils.getSortColumnList());
        map.put("hiddenFiledsJson", hiddenFiledsJson);

        //enum
        fmUtils.genOptionDataEnumFile(optionDataList);
        fmUtils.genEnumTag(map);
        fmUtils.genOptionEnumFile4ColumnSelf(option4ColumnSelfList);
        //按模板生成各种文件
        fmUtils.genFile(map,type);
    }



}
